//
//  ZLPageCurlController.m
//  AnimationDemo
//
//  Created by Jiaozl on 2021/1/16.
//  Copyright © 2021 Jiaozl. All rights reserved.
//

#import "ZLPageCurlController.h"
#import "UIView+additional.h"
#import "UIView+BGFrame.h"

@interface ZLPageCurlController ()

@property (nonatomic, strong) UIImage *fromImage;   ///<
@property (nonatomic, strong) UIImage *toImage;   ///<
@property (nonatomic, strong) UIImage *toMirroredImage;   ///<


@property (nonatomic, strong) UIImageView *fromImageView;   ///<
@property (nonatomic, strong) UIImageView *toImageView;   ///<
@property (nonatomic, strong) UIImageView *leftAnimationImageView;   ///<

@property (nonatomic, strong) UISlider *slider;   ///<
@property (nonatomic, strong) UILabel *progressLabel;   ///<
@property (nonatomic, assign) CGFloat lastProgress;  ///<

@end

@implementation ZLPageCurlController

#pragma mark - Life Cycle

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
    [self setupConstraints];
    
    self.progressLabel.text = [NSString stringWithFormat:@"%.2f", self.slider.value];
    
    UIImage * image = [self generateImageWithView:self.fromImageView];
    NSArray *fromImages = [self cutImagesWithSourceImage:image rect:self.fromImageView.bounds];
    self.leftAnimationImageView.image = fromImages[0];
    UILabel *dotLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
    dotLabel.backgroundColor = UIColor.redColor;
    dotLabel.clipsToBounds = YES;
    dotLabel.layer.cornerRadius = dotLabel.width * 0.5;
    [self.leftAnimationImageView addSubview:dotLabel];
    self.leftAnimationImageView.backgroundColor = UIColor.blackColor;
    [self toMirroredImage];
}

- (void)dealloc {
    NSLog(@"Jiaozl %s", __func__);
}

#pragma mark - Private Method

- (void)setupUI {
    self.view.backgroundColor = UIColor.whiteColor;
    [self.view addSubview:self.toImageView];
    [self.view addSubview:self.fromImageView];
    
    [self.view addSubview:self.slider];
    [self.view addSubview:self.progressLabel];
    
    [self.toImageView addSubview:self.leftAnimationImageView];
}

- (void)setupConstraints {
    self.fromImageView.frame = CGRectMake(100, 100, 150, 150);
    self.toImageView.frame = self.fromImageView.frame;
    
    self.slider.frame = CGRectMake(100, 400, 250, 40);
    self.slider.centerX = self.view.centerX;
    self.progressLabel.size = CGSizeMake(300, 40);
    self.progressLabel.centerX = self.view.centerX;
    self.progressLabel.bottom = self.slider.top;
    
    self.leftAnimationImageView.frame = self.toImageView.frame;
    self.leftAnimationImageView.left = 0;
    self.leftAnimationImageView.top = 0;
    self.leftAnimationImageView.width = self.toImageView.width * 0.5;
}

- (void)didChange:(UISlider *)slider {
    self.progressLabel.text = [NSString stringWithFormat:@"%.2f", self.slider.value];
    
    if (fabs(slider.value - self.lastProgress) > 0.1) {
        self.lastProgress = slider.value;
        [self animationWithProgress:self.slider.value];
    }
}

- (void)animationWithProgress:(CGFloat)progress {
    if (progress < 0.5) {
        self.fromImageView.image = self.toMirroredImage;
    } else {
        self.fromImageView.image = self.fromImage;
    }
    
    //设置立体效果，近大远小
    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = -1.0 / 500;
    CGFloat angle = -((1.0 - progress)) * M_PI;
    
    //    NSLog(@"Jiaozl %.f", self.fromImageView.width);
    
    [CATransaction begin];
    [CATransaction disableActions];
    //    self.fromImageView.layer.anchorPoint = CGPointMake(0., 0.);
    self.fromImageView.layer.transform = CATransform3DRotate(transform, angle, .0, 1.0, .0);
    [CATransaction commit];
}

- (UIImage *)rotateImage:(UIImage *)image orient:(UIImageOrientation)orient {
    if (!image) {
        return nil;
    }
    @autoreleasepool {
        UIImage *res = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orient];
        return res;
    }
    return nil;
}

- (UIImage *)generateImageWithView:(UIView *)view {
    if (!view) {
        return nil;
    }
    UIView *subView = view;
    CGSize size = CGSizeMake(ceilf(view.bounds.size.width), ceilf(view.bounds.size.height));
    @autoreleasepool {
        if (@available(iOS 10.0, *)) {
            UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithBounds:CGRectMake(0, 0, size.width, size.height)];
            return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
                [subView.layer renderInContext:rendererContext.CGContext];
                //                subView.layer.contents = nil;
            }];
        } else {
            UIGraphicsBeginImageContextWithOptions(size, YES, 0);
            CGContextRef ctx = UIGraphicsGetCurrentContext();
            [subView.layer renderInContext:ctx];
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
            subView.layer.contents = nil;
            UIGraphicsEndImageContext();
            CGContextRelease(ctx);
            return image;
        }
    }
    return nil;
}

- (NSArray <UIImage *>*)cutImagesWithSourceImage:(UIImage *)sourceImage rect:(CGRect)rect {
#if 1
    {
        if (!sourceImage) {
            return nil;
        }
        
        CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) {
            return deg / 180.0f * (CGFloat) M_PI;
        };
        
        CGRect leftRect = CGRectMake(0, 0, floor(rect.size.width / 2) , floor(rect.size.height));
        CGRect rightRect = CGRectMake(rect.size.width / 2, 0, floor(rect.size.width / 2) , floor(rect.size.height));
        
        CGAffineTransform rectTransform;
        switch (sourceImage.imageOrientation) {
            case UIImageOrientationLeft:
                rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -sourceImage.size.height);
                break;
            case UIImageOrientationRight:
                rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -sourceImage.size.width, 0);
                break;
            case UIImageOrientationDown:
                rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -sourceImage.size.width, -sourceImage.size.height);
                break;
            default:
                rectTransform = CGAffineTransformIdentity;
        };
        
        rectTransform = CGAffineTransformScale(rectTransform, sourceImage.scale, sourceImage.scale);
        
        // apply the transformation to the rect to create a new, shifted rect
        CGRect leftTransformedCropSquare = CGRectApplyAffineTransform(leftRect, rectTransform);
        CGImageRef leftCutImage = CGImageCreateWithImageInRect(sourceImage.CGImage, leftTransformedCropSquare);
        
        CGRect rightTransformedCropSquare = CGRectApplyAffineTransform(rightRect, rectTransform);
        CGImageRef rightCutImage = CGImageCreateWithImageInRect(sourceImage.CGImage, rightTransformedCropSquare);
        //将切割出得图片转换为UIImage
        UIImage *leftResultImage = [UIImage imageWithCGImage:leftCutImage];
        UIImage *rightResultImage = [UIImage imageWithCGImage:rightCutImage];
        
        CGImageRelease(leftCutImage);
        CGImageRelease(rightCutImage);
        if (!leftResultImage || !rightResultImage) {
            return nil;
        }
        return @[leftResultImage, rightResultImage];
    }
#else
    {
        
        //把像 素rect 转化为 点rect（如无转化则按原图像素取部分图片）
        CGFloat scale = [UIScreen mainScreen].scale;
        CGFloat x= rect.origin.x*scale,
        y=rect.origin.y*scale,
        w=rect.size.width*scale,
        h=rect.size.height*scale;
        CGRect dianRect = CGRectMake(x, y, w * 0.5, h);
        
        //截取部分图片并生成新图片
        CGImageRef sourceImageRef = [sourceImage CGImage];
        CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, dianRect);
        UIImage *leftResultImage = [UIImage imageWithCGImage:newImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
        
        dianRect = CGRectMake(w * 0.5, y, w * 0.5, h);
        CGImageRef rightImageRef = CGImageCreateWithImageInRect(sourceImageRef, dianRect);
        UIImage *rightResultImage = [UIImage imageWithCGImage:rightImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
        return @[leftResultImage, rightResultImage];
    }
#endif
}

#pragma mark - Getter

- (UIImage *)fromImage {
    if (!_fromImage) {
        _fromImage = [UIImage imageNamed:@"from"];
    }
    return _fromImage;;
}

- (UIImage *)toImage {
    if (!_toImage) {
        _toImage = [UIImage imageNamed:@"to"];
    }
    return _toImage;;
}

- (UIImageView *)fromImageView {
    if (!_fromImageView) {
        _fromImageView = [[UIImageView alloc] initWithImage:self.fromImage];
    }
    return _fromImageView;
}

- (UIImageView *)toImageView {
    if (!_toImageView) {
        _toImageView = [[UIImageView alloc] initWithImage:self.toImage];
    }
    return _toImageView;
}

- (UIImage *)toMirroredImage {
    if (!_toMirroredImage) {
        _toMirroredImage = [self rotateImage:self.toImage orient:UIImageOrientationUpMirrored];
    }
    return _toMirroredImage;
}

- (UISlider *)slider {
    if (!_slider) {
        _slider = [[UISlider alloc] init];
        _slider.minimumValue = 0;
        _slider.maximumValue = 1;
        _slider.value = _slider.maximumValue;
        [_slider addTarget:self action:@selector(didChange:) forControlEvents:UIControlEventValueChanged];
    }
    return _slider;
}

- (UILabel *)progressLabel {
    if (!_progressLabel) {
        _progressLabel = [[UILabel alloc] init];
        _progressLabel.textColor = UIColor.lightGrayColor;
        _progressLabel.text = @"0";
        _progressLabel.textAlignment = NSTextAlignmentCenter;
    }
    return _progressLabel;
}

- (UIImageView *)leftAnimationImageView {
    if (!_leftAnimationImageView) {
        _leftAnimationImageView = [[UIImageView alloc] init];
    }
    return _leftAnimationImageView;
}

@end
